#include <QtWidgets>
#include "kcalc.h"
#include <iostream>
#include <string>
#include <map>
#include <cctype>
#include <sstream>
Kcalc::Kcalc (QWidget *parent):QDialog(parent)
{
    setupUi(this);
    connect(lineEdit_2,SIGNAL(returnPressed()),this,SLOT(calculate()));
}


double core::expr(bool get)
{
    using namespace std;

    double term(bool);
    double left = term(get);
    for (;;){
        switch (curr_tok){
        case PLUS:
            left += term(true);
            break;
        case MINUS:
            left -= term(true);
            break;
        default:
            return left;
        }
    }
}

double core::term(bool get)
{
    using namespace std;
    double prim(bool);
    double left = prim(get);
    for (;;){
        switch(curr_tok) {
        case MUL:
            left *= prim(true);
            break;
        case DIV:
            if (double d = prim(true)) {
                left /= d;
                break;
            }
        default:
            return left;
        }
    }
}


double core::prim(bool get)
{
    using namespace std;

    map<string,double>table;
    token_value get_token();
    double expr(bool);

    if(get) get_token();

    switch(curr_tok) {
    case NUMBER:
    {
        double v = number_value;
        get_token();
        return v;
    }
    case NAME:
    {
        double& v = table[string_value];
        if(get_token() == ASSIGN) v = expr(true);
        return v;
    }
    case MINUS:
        return -prim(true);
    case LP:
    {
        double e = expr(true);
        get_token();
        return e;
    }
    default:
        return 0;
}
   
}

core::token_value core::curr_tok ;
double core::number_value;
std::string core::string_value;

core::token_value core::get_token()

{
    using namespace std;

    char ch = 0;
    cin >> ch;
    switch (ch){
    case ';':
    case '\n':
        return curr_tok = PRINT;
    case '*':
    case '/':
    case '-':
    case '+':
    case '(':
    case ')':
    case '=':
        return curr_tok = token_value(ch);
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    case '.':
        cin.putback(ch);
        cin >>  number_value;
        return curr_tok=NUMBER;
    default:
        if (isalpha(ch)) {
            string_value = ch;
            while (cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
            cin.putback(ch);
            return curr_tok=NAME;
        }
    }
        return curr_tok = PRINT;
}


int Kcalc::calculate()
{
    using namespace core;
    //double expr(double get);
    // double term(double get);
    // double prim(double get);
    // core::token_value core::get_token();
    
    //while (lineEdit_2->text()){
    //lineEdit_2->text() >>std::cin;
//    QString str = lineEdit_2->text();
    while(QString::length(str) != 0){
         get_token();
         if (curr_tok == END)break;//goto a;
        if (curr_tok != PRINT)
            lineEdit->setText(QString::number(expr(false),'f',2)) ;
           }
    return 0;
}

//emit rectangleLengthWidth(lengthString,widthString);

